package org.example.sync.guarded;

import lombok.Data;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.example.utils.Downloader;

import java.io.IOException;
import java.util.List;

/**
 * @author zhengdp
 * @Description 保护性暂停模式实现
 * @Date 2022/10/12 22:29
 * @Created by zhengdp
 */
@Slf4j(topic = "c.guardedTest")
public class GuardedTest {

    /**
     * 线程1 等待 线程2的下载结果
     * @param args
     */
    @SneakyThrows
    public static void main(String[] args) {
        GuardedObject obj = new GuardedObject();
        new Thread(() -> {
            log.info("等待结果");
            // 等待结果
            List<String> line2 = (List<String>) obj.get();
            log.info("获取到结果对象大小 : [{}]",line2.size());
        },"t1").start();

        Thread.sleep(2000);

        // 线程2 进行下载
        new Thread(() -> {
            log.info("执行下载");
            try {
                List<String> list = Downloader.download();
                obj.complete(list);
            } catch (IOException e) {
                throw new RuntimeException(e);
            }
        },"t2").start();
    }

}

/**
 * 测试未超时情况
 */
@Slf4j(topic = "c.guardedTest")
class TestNoTimeOut {
    // 超时测试
    public static void main(String[] args) {
        GuardedObject obj = new GuardedObject();
        new Thread(() -> {
            // 获取结果
            log.info("获取结果 ....");
            Object o = obj.get(2000);
            log.info("结果信息 : {}",o);
        },"t1").start();

        // 设置结果
        new Thread(() -> {
            // 未超时情况
            log.info("设置结果");
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
            obj.complete(new Object());
        },"t2").start();
    }
}

/**
 * 测试超时情况
 */
@Slf4j(topic = "c.guardedTest")
class TestTimeout {
    // 超时测试
    public static void main(String[] args) {
        GuardedObject obj = new GuardedObject();
        new Thread(() -> {
            // 获取结果
            log.info("获取结果 ....");
            Object o = obj.get(2000);
            log.info("结果信息 : {}",o);
        },"t1").start();

        // 设置结果
        new Thread(() -> {
            // 未超时情况
            log.info("设置结果");
            try {
                Thread.sleep(3000);
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
            obj.complete(new Object());
        },"t2").start();
    }
}

/**
 * 测试虚假唤醒情况
 */
@Slf4j(topic = "c.guardedTest")
class TestFakeNotify {
    // 超时测试
    public static void main(String[] args) {
        GuardedObject obj = new GuardedObject();
        new Thread(() -> {
            // 获取结果
            log.info("获取结果 ....");
            Object o = obj.get(2000);
            log.info("结果信息 : {}",o);
        },"t1").start();

        // 设置结果
        new Thread(() -> {
            // 未超时情况
            log.info("设置结果");
            try {
                Thread.sleep(1000);
                obj.complete(null);
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }


        },"t2").start();
    }
}

